﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.Cryptography;
using System.Reflection;
using System.Diagnostics;
using System.Drawing;

namespace System
{
    /// <summary>
    /// Constants
    /// </summary>
    public static class Constants
    {
        /// <summary>
        /// \n
        /// </summary>
        public const string NewLineWindows = "\n";

        /// <summary>
        /// \r\n
        /// </summary>
        public const string NewLineLinux = "\r\n";
    }

    /// <summary>
    /// 
    /// </summary>
    public static class StringExt
    {
        /// <summary>
        /// Compares as string with number words.
        /// </summary>
        /// <param name="value1">The value1.</param>
        /// <param name="value2">The value2.</param>
        /// <returns></returns>
        public static int CompareAsStringWithNumberWords(this string value1, string value2)
        {
            List<string> parts1 = value1.GetMatches("(([^0-9]+)|([0-9]+))");
            List<string> parts2 = value2.GetMatches("(([^0-9]+)|([0-9]+))");
            int tmp;
            string p1, p2;
            double db1, db2;
            for (int i = 0; i < parts1.Count; i++)
            {
                if (parts2.Count <= i)
                    return 1;
                p1 = parts1[i];
                p2 = parts2[i];
                if (double.TryParse(p1, out db1) && double.TryParse(p2, out db2))
                {
                    tmp = db1.CompareTo(db2);
                    if (tmp != 0)
                        return tmp;
                }
                else
                {
                    tmp = p1.CompareTo(p2);
                    if (tmp != 0)
                        return tmp;
                }
            }
            if (parts2.Count > parts1.Count)
                return -1;
            return 0;
        }

        #region encryption

        /// <summary>
        /// Encrypts using DES.
        /// </summary>
        /// <param name="originalString">The original string.</param>
        /// <param name="pass">The pass.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">The string which needs to be encrypted can not be null.</exception>
        public static string EncryptDes(this string originalString, string pass = "CoolPass")
        {
            if (String.IsNullOrEmpty(originalString))
            {
                throw new ArgumentNullException
                       ("The string which needs to be encrypted can not be null.");
            }
            byte[] bytes = ASCIIEncoding.ASCII.GetBytes(pass);
            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream,
                cryptoProvider.CreateEncryptor(bytes, bytes), CryptoStreamMode.Write);
            StreamWriter writer = new StreamWriter(cryptoStream);
            writer.Write(originalString);
            writer.Flush();
            cryptoStream.FlushFinalBlock();
            writer.Flush();
            return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
        }
        /// <summary>
        /// Decrypts using DES.
        /// </summary>
        /// <param name="cryptedString">The crypted string.</param>
        /// <param name="pass">The pass.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">The string which needs to be decrypted can not be null.</exception>
        public static string DecryptDes(this string cryptedString, string pass = "CoolPass")
        {
            if (String.IsNullOrEmpty(cryptedString))
            {
                throw new ArgumentNullException
                   ("The string which needs to be decrypted can not be null.");
            }
            byte[] bytes = ASCIIEncoding.ASCII.GetBytes(pass);
            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
            MemoryStream memoryStream = new MemoryStream
                    (Convert.FromBase64String(cryptedString));
            CryptoStream cryptoStream = new CryptoStream(memoryStream,
                cryptoProvider.CreateDecryptor(bytes, bytes), CryptoStreamMode.Read);
            StreamReader reader = new StreamReader(cryptoStream);
            return reader.ReadToEnd();
        }
        #endregion

        /// <summary>
        /// Gets the common prefix.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static string GetCommonPrefix(this string value, string str)
        {
            if (value.IsNull() || str.IsNull())
                return "";
            int i = 0;
            for (i = 0; i < value.Length; i++)
            {
                if (str.Length <= i)
                    break;
                if (str[i] != value[i])
                    break;
            }
            return value.SubstringSafe(0, i);
        }
        /// <summary>
        /// Trims the start and end.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="chars">The chars.</param>
        /// <returns></returns>
        public static string TrimStartEnd(this string str, params char[] chars)
        {
            return str.Trim(chars);
        }

        #region ByteArray
        /// <summary>
        /// Converts value to byte array.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="enc">The encoding.</param>
        /// <returns></returns>
        public static byte[] AsByteArray(this string str, Encoding enc)
        {
            return enc.GetBytes(str);
        }
        /// <summary>
        /// Converts value to byte array.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static byte[] AsByteArray(this string str)
        {
            return str.AsByteArray(Encoding.UTF8);
        }

        /// <summary>
        /// Converts byte array to string.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <param name="enc">The encoding.</param>
        /// <returns></returns>
        public static string ByteArrayToString(this byte[] bytes, Encoding enc)
        {
            return enc.GetString(bytes);
        }
        /// <summary>
        /// Converts byte array to string.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <returns></returns>
        public static string ByteArrayToString(this byte[] bytes)
        {
            return bytes.ByteArrayToString(Encoding.UTF8);
        }
        #endregion

        #region Substring
        /// <summary>
        /// Substrings the safe.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="startIndex">The start index.</param>
        /// <param name="length">The length.</param>
        /// <returns></returns>
        public static string SubstringSafe(this string str, int startIndex, int length)
        {
            int len = str.AsString().Length - startIndex;
            if(length>len)
                length = len;
            if (length < 0)
                return string.Empty;
            return str.AsString().Substring(startIndex, length);
        }
        /// <summary>
        /// Substrings the safe.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="startIndex">The start index.</param>
        /// <returns></returns>
        public static string SubstringSafe(this string str, int startIndex)
        {
            return str.SubstringSafe(startIndex, str.AsString().Length - startIndex);
        }
        #endregion

        #region null, empty, whitespace
        /// <summary>
        /// Determines whether specified string is null or empty
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }
        /// <summary>
        /// Determines whether specified string is not null or empty
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static bool IsNotNullOrEmpty(this string str)
        {
            return !str.IsNullOrEmpty();
        }
        /// <summary>
        /// Determines whether specified string is null or white space
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static bool IsNullOrWhiteSpace(this string str)
        {
            return string.IsNullOrWhiteSpace(str);
        }
        /// <summary>
        /// Determines whether specified string is not null or white space
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static bool IsNotNullOrWhiteSpace(this string str)
        {
            return !str.IsNullOrWhiteSpace();
        }
        #endregion

        #region Regular expresions
        /// <summary>
        /// Gets list of matches
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="pattern">Pattern</param>
        /// <param name="groups">groups to return</param>
        /// <param name="options">RegexOptions</param>
        /// <returns></returns>
        public static List<Dictionary<int, string>> GetMatches(this string value, string pattern, int[] groups , RegexOptions options = RegexOptions.IgnoreCase)
        {
            List<Dictionary<int, string>> list = new List<Dictionary<int, string>>();
            if (groups != null)
            {
                MatchCollection coll = value.XMatches(pattern, options);
                Dictionary<int, string> dic = null;
                foreach (Match m in coll)
                {
                    dic = new Dictionary<int, string>();
                    list.Add(dic);
                    foreach (int group in groups)
                    {
                        dic.Add(group, m.Groups[group].Value);
                    }
                }
            }
            return list;
        }

        /// <summary>
        /// Gets list of matches for single group
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="pattern">Pattern</param>
        /// <param name="group">Group</param>
        /// <param name="options">RegexOptions</param>
        /// <returns></returns>
        public static List<string> GetMatches(this string value, string pattern, int group = 1, RegexOptions options = RegexOptions.IgnoreCase)
        {
            List<string> list = new List<string>();
            List<Dictionary<int, string>> l = value.GetMatches(pattern, new int[] { group }, options);
            foreach (Dictionary<int, string> d in l)
            {
                list.AddRange(d.Values);
            }
            return list;
        }

        /// <summary>
        /// Gets first match for some groups. null is returned if value does not match pattern
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="pattern">Pattern</param>
        /// <param name="groups">Groups</param>
        /// <param name="options">RegexOptions</param>
        /// <returns></returns>
        public static Dictionary<int, string> GetFirstMatch(this string value, string pattern, int[] groups, RegexOptions options = RegexOptions.IgnoreCase)
        {
            List<Dictionary<int, string>> l = value.GetMatches(pattern, groups, options);
            if (l.Count > 0)
                return l[0];
            return null;
        }

        /// <summary>
        /// Gets first match
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="pattern">Pattern</param>
        /// <param name="group">Group</param>
        /// <param name="options">RegexOptions</param>
        /// <returns></returns>
        public static string GetFirstMatch(this string value, string pattern, int group = 1, RegexOptions options = RegexOptions.IgnoreCase)
        {
            Dictionary<int, string> d = value.GetFirstMatch(pattern, new int[] { group }, options);
            if (d != null)
                return d[group];
            return string.Empty;
        }

        /// <summary>
        /// Gets matches
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="pattern">Pattern</param>
        /// <param name="options">RegexOptions</param>
        /// <returns></returns>
        public static MatchCollection XMatches(this string value, string pattern, RegexOptions options = RegexOptions.IgnoreCase)
        {
            return Regex.Matches(value, pattern, options);
        }

        /// <summary>
        /// Check if string matches pattern
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="pattern">The pattern.</param>
        /// <param name="options">The options.</param>
        /// <returns></returns>
        public static bool XMatch(this string value, string pattern, System.Text.RegularExpressions.RegexOptions options = RegexOptions.IgnoreCase)
        {
            bool result = false;
            try
            {
                result = Regex.IsMatch(value, pattern, options);
            }
            catch { }
            return result;
        }
        /// <summary>
        /// Splits string
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="pattern">The pattern.</param>
        /// <param name="options">The options.</param>
        /// <returns></returns>
        public static string[] XSplit(this string value, string pattern, RegexOptions options = RegexOptions.IgnoreCase)
        {
            return Regex.Split(value, pattern, options);
        }


        /// <summary>
        /// Replaces string with another string
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="pattern">The pattern.</param>
        /// <param name="replacement">The replacement.</param>
        /// <param name="options">The options.</param>
        /// <returns></returns>
        public static string XReplace(this string value, string pattern, string replacement, RegexOptions options = RegexOptions.IgnoreCase)
        {
            return Regex.Replace(value, pattern, replacement, options);
        }

        /// <summary>
        /// specials
        /// </summary>
        private static string[] specials = new string[]{
                        "\\","/", ".", "*", "+", "?", "|",
                        "(", ")", "[", "]", "{", "}", 
                        "$", "^"
        };

        /// <summary>
        /// Escapes special chars for Regular Expressions
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string XEscape(this string value)
        {
            if (value != null)
            {
                foreach (string s in specials)
                {
                    value = value.Replace(s, "\\" + s);
                }
            }
            return value;
        }
        /// <summary>
        /// Formats string by replacing {x} with object from args.
        /// x starts with 0
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="args">The arguments.</param>
        /// <returns></returns>
        public static string XFormat(this string value, params object[] args)
        {
            if (args != null)
            {
                int i = 0;
                foreach (object o in args)
                {
                    value = value.XReplace(@"\{\s*" + i + @"\s*\}", o.AsString());
                    i++;
                }
            }
            return value;
        }
        #endregion

        #region SQL
        /// <summary>
        /// Replaces ' with ''
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string PrepareString(this string value)
        {
            return value.AsString().Replace("'", "''");
        }

        /// <summary>
        /// Prepares string and adds single quotes
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string EscapeSql(this string value)
        {
            string s = value.PrepareString();
            s = "'" + s + "'";
            return s;
        }

        /// <summary>
        /// Adds AND if value is not empty
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string AppendAnd(this string value)
        {
            return value.AppendString(" AND ");
        }
        /// <summary>
        /// Adds OR if value is not empty
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string AppendOr(this string value)
        {
            return value.AppendString(" OR ");
        }
        #endregion

        #region add strings
        /// <summary>
        /// Adds prefix, and surfix to value
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="prefix">The prefix.</param>
        /// <param name="surfix">The surfix.</param>
        /// <returns></returns>
        public static string PutBetween(this string value, string prefix, string surfix)
        {
            return prefix + value + surfix;
        }

        /// <summary>
        /// Adds str as prefix and surfix
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static string PutBetween(this string value, string str)
        {
            return value.PutBetween(str, str);
        }

        /// <summary>
        /// Adds " in front and at the end of string
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string AddDoubleQuotes(this string value)
        {
            return value.PutBetween("\"");
        }

        /// <summary>
        /// If value is not empty adds appender
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="appender">The appender.</param>
        /// <returns></returns>
        public static string AppendString(this string value, string appender)
        {
            if (value.IsNotNull())
                return value + appender;
            return value;
        }

        /// <summary>
        /// Adds appender in new line if value is not empty, or returns appender
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="appender">The appender.</param>
        /// <param name="newLineStr">The new line string.</param>
        /// <returns></returns>
        public static string AppendLine(this string value, string appender, string newLineStr = Constants.NewLineLinux)
        {
            return value.AppendString(newLineStr) + appender;
        }

        /// <summary>
        /// Replaces \n withh \r\n
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string ReplaceSingleEOL(this string value)
        {
            return value.AsString().Replace(Constants.NewLineWindows, Constants.NewLineLinux);
        }
        /// <summary>
        /// Replaces \r\n with \n
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string ReplaceDoubleEOL(this string value)
        {
            return value.AsString().Replace(Constants.NewLineLinux, Constants.NewLineWindows);
        }
        #endregion

        #region FileOperations
        /// <summary>
        /// Reads the file.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
        public static string ReadFile(this string FileName)
        {
            string str = "";
            try
            {
                FileStream fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                if (fs != null)
                {
                    StreamReader r = new StreamReader(fs);
                    str = r.ReadToEnd();
                    r.Close();
                    fs.Close();
                }
            }
            catch { }
            return str;
        }

        /// <summary>
        /// Writes to file.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="FileName">Name of the file.</param>
        /// <param name="throwException">if set to <c>true</c> [throw exception].</param>
        /// <param name="logException">if set to <c>true</c> [log exception].</param>
        /// <param name="writeLine">if set to <c>true</c> New line will be added at the end of file.</param>
        public static void WriteToFile(this string value, string FileName, bool throwException = false, bool logException = true, bool writeLine = false)
        {
            value.WriteToFile(FileName, Encoding.UTF8, throwException, logException, writeLine);
        }
        /// <summary>
        /// Writes to file.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="FileName">Name of the file.</param>
        /// <param name="encoding">The encoding.</param>
        /// <param name="throwException">if set to <c>true</c> [throw exception].</param>
        /// <param name="logException">if set to <c>true</c> [log exception].</param>
        /// <param name="writeLine">if set to <c>true</c> New line will be added at the end of file.</param>
        public static void WriteToFile(this string value, string FileName, Encoding encoding,  bool throwException = false, bool logException = true, bool writeLine = false)
        { 
            FileStream fs = null;
            System.IO.StreamWriter sw = null;
            try
            {
                fs = System.IO.File.Open(FileName, System.IO.FileMode.Create);
                sw = new System.IO.StreamWriter(fs, encoding);
                if(writeLine)
                    sw.WriteLine(value);
                else
                    sw.Write(value);
                sw.Flush();
            }
            catch (Exception ex)
            {
                if (logException)
                    ex.LogInternal();
                if (throwException)
                    throw ex;
            }
            finally
            {
                try
                {
                    if (sw != null)
                        sw.Close();
                    if (fs != null)
                        fs.Close();
                }
                catch { }
            }
        }

        /// <summary>
        /// Appends to file.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="FileName">Name of the file.</param>
        /// <param name="throwException">if set to <c>true</c> [throw exception].</param>
        /// <param name="logException">if set to <c>true</c> [log exception].</param>
        /// <param name="writeLine">if set to <c>true</c> New line will be added at the end of file.</param>
        public static void AppendToFile(this string value, string FileName, bool throwException = false, bool logException = true, bool writeLine = true)
        {
            value.AppendToFile(FileName, Encoding.UTF8, throwException, logException, writeLine);
        }
        /// <summary>
        /// Appends to file.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="FileName">Name of the file.</param>
        /// <param name="encoding">The encoding.</param>
        /// <param name="throwException">if set to <c>true</c> [throw exception].</param>
        /// <param name="logException">if set to <c>true</c> [log exception].</param>
        /// <param name="writeLine">if set to <c>true</c> New line will be added at the end of file.</param>
        public static void AppendToFile(this string value, string FileName, Encoding encoding, bool throwException = false, bool logException = true, bool writeLine = true)
        {
            FileStream fs = null;
            System.IO.StreamWriter sw = null;
            try
            {
                fs = System.IO.File.Open(FileName, System.IO.FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                sw = new System.IO.StreamWriter(fs, encoding);
                if (writeLine)
                    sw.WriteLine(value);
                else
                    sw.Write(value);
                sw.Flush(); 
            }
            catch (Exception ex)
            {
                if (logException)
                    ex.LogInternal();
                if (throwException)
                    throw ex;
            }
            finally
            {
                try
                {
                    if (sw != null)
                        sw.Close();
                    if (fs != null)
                        fs.Close();
                }
                catch (Exception ex2) { ex2.LogInternal(); }
            }
        }

        //public static void LogToFile(this string value)
        //{
        //    value.AppendToFile("c:\\tmp.txt");
        //}
        #endregion

        /// <summary>
        /// Sets first letter to upercase.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static string FirstLetterUpper(this string str)
        {
            string s = "";
            bool isWord = true;
            foreach (char c in str)
            {
                if (isWord)
                {
                    isWord = false;
                    if (char.IsLetter(c))
                    {
                        s += char.ToUpper(c);
                    }
                    else
                    {
                        s += c;
                    }
                }
                else
                {
                    s += c;
                }
                isWord = char.IsWhiteSpace(c);
            }
            return s;
        }
        /// <summary>
        /// Replaces the polish chars.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        public static string ReplacePolishChars(this string str)
        {
            str = str.Replace("ś", "s");
            str = str.Replace("Ś", "S");

            str = str.Replace("ć", "c");
            str = str.Replace("Ć", "C");

            str = str.Replace("ź", "z");
            str = str.Replace("Ź", "Z");

            str = str.Replace("ż", "z");
            str = str.Replace("Ż", "Z");

            str = str.Replace("Ó", "O");
            str = str.Replace("ó", "o");

            str = str.Replace("ń", "n");
            str = str.Replace("Ń", "N");

            str = str.Replace("ą", "a");
            str = str.Replace("Ą", "A");

            str = str.Replace("ę", "e");
            str = str.Replace("Ę", "E");

            str = str.Replace("ł", "l");
            str = str.Replace("Ł", "L");
            return str;
        }
        /// <summary>
        /// Sorts as string with number words.
        /// </summary>
        /// <param name="list">The list.</param>
        public static void SortAsStringWithNumberWords(this List<string> list)
        {
            list.Sort(CompareAsStringWithNumberWords);
        }
        /// <summary>
        /// Mesures the specified string.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="font">The font.</param>
        /// <returns></returns>
        public static System.Drawing.Size Mesure(this string value, System.Drawing.Font font)
        {
            return System.Windows.Forms.TextRenderer.MeasureText(value, font);
        }

        /// <summary>
        /// To the multi words.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static string ToMultiWords(this string value)
        {
            string val = "";
            if (value.IsNotNull())
            {
                bool skip = false;
                foreach (char c in value)
                {
                    if (Char.IsUpper(c))
                    {
                        if (!skip)
                        {
                            val = val.AppendString(" ");
                        }
                        skip = true;
                    }
                    else
                    {
                        if (Char.IsWhiteSpace(c))
                            skip = true;
                        else
                            skip = false;
                    }
                    val += c;
                }
            }
            return val;
        }

        /// <summary>
        /// To the lines.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="skipEmpty">if set to <c>true</c> [skip empty].</param>
        /// <param name="allowDuplitates">if set to <c>true</c> [allow duplitates].</param>
        /// <param name="trim">if set to <c>true</c> [trim].</param>
        /// <returns></returns>
        public static List<string> ToLines(this string value, bool skipEmpty = true, bool allowDuplitates = false, bool trim = true)
        {
            List<string> list = new List<string>();
            if (value != null)
            {
                string[] str = value.Split('\n');
                string val;
                foreach (string s in str)
                {
                    val = s;
                    if (trim)
                        val = val.Trim();
                    if (!skipEmpty || val.IsNotNullOrWhiteSpace())
                    {
                        if (!list.Contains(val) || allowDuplitates)
                        {
                            list.Add(val);
                        }
                    }
                }
            }
            return list;
        }

        /// <summary>
        /// Splits the specified value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="splitter">The splitter.</param>
        /// <param name="options">The options.</param>
        /// <returns></returns>
        public static string[] Split(this string value, string splitter, StringSplitOptions options = StringSplitOptions.RemoveEmptyEntries)
        {
            return value.Split(new string[] { splitter }, options);
        }

        #region Logs
        /// <summary>
        /// Logs the error.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogError(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogError(message, null);
        }
        /// <summary>
        /// Logs the information.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogInfo(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogInfo(message, null);
        }
        /// <summary>
        /// Logs the warning.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogWarning(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogWarning(message, null);
        }
        /// <summary>
        /// Logs the debug.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogDebug(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogDebug(message, null);
        }
        /// <summary>
        /// Logs the internal.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogInternal(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogInternal(message, null);
        }
        /// <summary>
        /// Logs all.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogAll(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogAll(message, null);
        }
        /// <summary>
        /// Logs the user1.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogUser1(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogUser1(message, null);
        }
        /// <summary>
        /// Logs the user2.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogUser2(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogUser2(message, null);
        }
        /// <summary>
        /// Logs the user3.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void LogUser3(this string message)
        {
            ProgNetComponents.Logs.Logger.Default.LogUser3(message, null);
        }

        #endregion

        /// <summary>
        /// Makes the name of the valid file.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="invalidCharReplacement">The invalid character replacement.</param>
        /// <returns></returns>
        public static string MakeValidFileName(this string name, char invalidCharReplacement = '_')
        {
            var builder = new StringBuilder();
            var invalid = System.IO.Path.GetInvalidFileNameChars();
            foreach (var cur in name)
            {
                if (!invalid.Contains(cur))
                {
                    builder.Append(cur);
                }
                else
                {
                    if (!invalid.Contains(invalidCharReplacement))
                        builder.Append(invalidCharReplacement);
                }
            }
            return builder.ToString();
        }
        /// <summary>
        /// Makes the valid path.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="invalidCharReplacement">The invalid character replacement.</param>
        /// <returns></returns>
        public static string MakeValidPath(this string name, char invalidCharReplacement = '_')
        {
            var builder = new StringBuilder();
            var invalid = System.IO.Path.GetInvalidPathChars();
            foreach (var cur in name)
            {
                if (!invalid.Contains(cur))
                {
                    builder.Append(cur);
                }
                else
                {
                    if (!invalid.Contains(invalidCharReplacement))
                        builder.Append(invalidCharReplacement);
                }
            }
            return builder.ToString();
        }

        /// <summary>
        /// Formats the specified string.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns></returns>
        public static string FormatMe(this string str, params object[] parameters)
        {
            return string.Format(str, parameters);
        }
    }
}
